#include "Color.h"
#include <algorithm>
#include <iostream>

using namespace std;

Color::Color(double h, double s, double v)
:
    d_h(h),
    d_s(s),
    d_v(v)
{
    updateRgb();
}

void Color::updateHsv()
{
    double M = max(d_r, max(d_g, d_b));
    double m = min(d_r, min(d_g, d_b));
    double d = M - m;
    
    d_v = M;
    d_s = (M > 0.00001) ? d / M : 0.0;
    if (d_s == 0.0)
        d_h = 0.0;
    else
    {
        if (d_r == M)
            d_h = (d_g - d_b) / d;
        else if (d_g == M)
            d_h = 2 + (d_b - d_r) / d;
        else
            d_h = 4 + (d_r - d_g) / d;
        d_h /= 6;
        if (d_h < 0.0)
            d_h = 0.0;
    }
}

void Color::updateRgb()
{
    int hueCase = (int)(d_h * 6);
    double frac = 6 * d_h - hueCase;
    double lx = d_v * (1 - d_s);
    double ly = d_v * (1 - d_s * frac);
    double lz = d_v * (1 - d_s * (1 - frac));
    
    switch (hueCase)
    {
        case 0:
            //FALLING THROUGH
        case 6:
            d_r = d_v;
            d_g = lz;
            d_b = lx;
            break;
        case 1:
            d_r = ly;
            d_g = d_v;
            d_b = lx;
            break;
        case 2:
            d_r = lx;
            d_g = d_v;
            d_b = lz;
            break;
        case 3:
            d_r = lx;
            d_g = ly;
            d_b = d_v;
            break;
        case 4:
            d_r = lz;
            d_g = lx;
            d_b = d_v;
            break;
        case 5:
            d_r = d_v;
            d_g = lx;
            d_b = ly;
            break;            
    }    
    
}

void Color::changeHue(double h)
{
    d_h = h;
    updateRgb();
}

void Color::changeSat(double s)
{
    d_s = s;
    updateRgb();
}

void Color::changeVal(double v)
{
    d_v = v;
    updateRgb();
}